package com.iflytek.uoamp.agent.monitor.utils.ValidIP;

import com.iflytek.uoamp.agent.common.constants.CommonConstants;
import com.iflytek.uoamp.agent.common.util.Constant;
import com.iflytek.uoamp.agent.common.util.ReadAll;
import com.iflytek.uoamp.agent.common.util.WFile;
import com.iflytek.uoamp.agent.monitor.find.CMDExextor;
import com.iflytek.uoamp.agent.monitor.find.CMDExextor.ShellResult;
import com.iflytek.uoamp.agent.monitor.find.imp.baseitem.FindBaseMonitorItemAbs;
import com.iflytek.uoamp.agent.monitor.find.obj.NetWork;

import org.apache.log4j.Logger;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;

public class LinuxValidIP implements ValidIPInterface{
	
	private String ip;
	public LinuxValidIP(String ip){
		this.ip = ip;
	}
	
	public String getIp() {
		return ip;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}

	@Override
	public boolean isOK(){
		ShellResult result = CMDExextor.execut(CommonConstants.GETIP_PATH);
		String output = result.output;
		if(output==null || ip==null){
			return false;
		}
		if(Pattern.matches(Constant.IP_REGULAR, ip) && output.contains(ip)){
			return true;
		}
		return false;
	}
	
	/**
	 * 使用jdk提供的函数获取最有可能的IP地址；
	 * @return
	 */
	public static String getLocalIpAddr() {
		Enumeration<NetworkInterface> allNetInterfaces = null;
		try {
			allNetInterfaces = NetworkInterface.getNetworkInterfaces();
		} catch (SocketException e) {
			Logger.getRootLogger().error(e.getMessage(),e);
		}
		InetAddress ip = null;
		List<String> jdkFoundIP = new LinkedList<String>();
		while (allNetInterfaces.hasMoreElements()) {
			NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
			try {
				if (!netInterface.isLoopback()) {
					Enumeration<InetAddress> addresses = netInterface.getInetAddresses();
					while (addresses.hasMoreElements()) {
						ip = (InetAddress) addresses.nextElement();
						if(ip==null){
							continue;
						}
						
						Logger.getRootLogger().info(ip+"   "+ip.isSiteLocalAddress()+"  "+ip.isLinkLocalAddress());
						if (ip instanceof Inet4Address && ip.getHostAddress().indexOf(".") != -1 && !"127.0.0.1".equals(ip.getHostAddress()) && ip.isSiteLocalAddress() && !ip.isLinkLocalAddress()) {
							ShellResult result = CMDExextor.execut("ifconfig");
							String output = result.output;
							if(output.contains(ip.getHostAddress())){
								jdkFoundIP.add(ip.getHostAddress());
							}
						}
					}
				}
			} catch (SocketException e) {
				Logger.getRootLogger().error(e.getMessage(),e);
			}
		}
		if(jdkFoundIP.size()==1){
			return jdkFoundIP.get(0);
		}
		return null;
	}
	
	
	@Override
	public String guessIP(){
		String ip = getLocalIpAddr();
		if(ip!=null && !ip.isEmpty()){
			WFile.wf(CommonConstants.CLIENTIP_PATH, ip);
			return ip;
		}
		
		Logger.getRootLogger().info("run check ip...");
		ShellResult result = CMDExextor.execut(CommonConstants.GETIP_PATH);
		NetWork netWork = null;
		String output = result.output;
		String[] lines = output.split("\n");
		
		LinkedList<NetWork> network = new LinkedList<NetWork>();
		NetWork curnet = null;
		for(String cur:lines){
			if(cur.contains("Link encap")){
				if(curnet!=null){
					network.add(curnet);
				}
				curnet = new NetWork();
				curnet.setName(cur.split("Link encap")[0].trim());
				Logger.getRootLogger().info("add Link encap "+ curnet.getName());
			}else if(cur.contains("RX bytes")){
				String substr = cur.substring(cur.indexOf("RX bytes:")+9);
				String bytestr = substr.split(" ")[0];
				curnet.setTransportByte(bytestr);
				Logger.getRootLogger().info("add RX bytes "+ curnet.getTransportByte());
			}else if(cur.contains("Interrupt")){
				curnet.setInterrupt(cur);
				Logger.getRootLogger().info("add Interrupt "+ curnet.getInterrupt());
			}else if(cur.contains("inet addr:")){
				String substr = cur.substring(cur.indexOf("inet addr:")+10);
				String ipstr = substr.split(" ")[0];
				curnet.setIp(ipstr);
				Logger.getRootLogger().info("add inet addr "+ curnet.getIp());
			}
		}
		
		boolean isallow = false;
		
		for(NetWork cur:network){
			
			if(cur.getIp()==null || cur.getIp().equals("")){
				continue;
			}
			
			for(String head:FindBaseMonitorItemAbs.getSet()){
				if(cur.getIp().startsWith(head)){
					isallow = true;
					break;
				}
			}
			
			if(!isallow){
				continue;
			}

			
			if(cur.getTransportByte()==null || cur.getTransportByte().equals("") || cur.getTransportByte().equals("0")){
				isallow = false;
				continue;
			}
			
			netWork = cur;
			break;
		}
	
		if(netWork!=null && netWork.getIp()!=null && !"".equals(netWork.getIp())){
			WFile.wf(CommonConstants.CLIENTIP_PATH, netWork.getIp());
		}else{
			netWork = new NetWork();
			netWork.setIp(ReadAll.readAll(CommonConstants.CLIENTIP_PATH, "utf-8"));
		}
		
		return netWork.getIp();
		
	}
	
}
